package com.simple.handler.impl;

import com.simple.anno.AfterLogic;
import com.simple.anno.AgentClass;
import com.simple.anno.BeforeLogic;
import com.simple.handler.AbstractHandler;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

/**
 * 此模板用于代理类对象
 */
public class TemplateHandler extends AbstractHandler {

    /**
     * before 在原始方法调用前，被触发， after 在原始方法调用后触发
     */
    protected Method before, after;

    /**
     * beforeUseParam 前置方法，是否接收原始方法参数， true表示接收 false表示不接收参数
     * afterUseParam 后置方法，是否接收原始方法参数，true表示接收，false表示不接收参数
     */
    protected boolean beforeUseParam, afterUseParam;

    @Override
    public void before(Object... objects) throws InvocationTargetException, IllegalAccessException {
        before.setAccessible(true);
        if (beforeUseParam) {
            before.invoke(proxy, objects);
        } else {
            before.invoke(proxy);
        }
    }

    @Override
    public void after(Object... objects) throws InvocationTargetException, IllegalAccessException {
        after.setAccessible(true);
        if (afterUseParam) {
            after.invoke(proxy, objects);
        } else {
            after.invoke(proxy);
        }
    }

    public void init(Class<?> aClass) {
        super.init(aClass);
        Method[] methods = proxy.getClass().getDeclaredMethods();
        for (Method method : methods) {
            BeforeLogic beforeLogic = method.getDeclaredAnnotation(BeforeLogic.class);
            if (beforeLogic != null) {
                before = method;
                beforeUseParam = beforeLogic.isUseParam();
            }
            AfterLogic afterLogic = method.getDeclaredAnnotation(AfterLogic.class);
            if (afterLogic != null) {
                after = method;
                afterUseParam = afterLogic.isUseParam();
            }
            if (after != null && before != null) {
                break;
            }
        }
    }
}
